﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using RightControl.Model;
using RightControl.Common;
using RightControl.IService;
using System.Net;

namespace AlibabaCollector
{
    public class PageAnalyser {

        public static IProductService productService { get; set; }
        public static IProductImgService productImgService { get; set; }
        public static ISubProductImageService subProductImageService { get; set; }

        public static ISubProductSizeService subProductSizeService { get; set; }    
        
        public static string urlPattern = @"(http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%!&=]*)?)";

        public static ProductDetail GetDetail(string url, int userId, string category,List<ExportFields> exportfields) {
            try {
                ProductDetail prdDetail = new ProductDetail(url, userId, category);
                if (productService.IsNotExist(prdDetail)) {
                    prdDetail.SkuId = category + Common.RandomCode();
                    HtmlWeb client = new HtmlWeb();
                    client.UseCookies = true;
                    client.OverrideEncoding = Encoding.GetEncoding("gb2312");                
                    //WebProxy proxy = new WebProxy("1.199.194.222", 808);           
                    //HtmlDocument doc = client.Load(url);

                    string html = GetHtmlRet(url);
                    HtmlDocument doc = new HtmlDocument();
                    doc.LoadHtml(html);

                    if (doc != null) {
                        int prodId = CreateProduct(prdDetail, exportfields, doc);
                        prdDetail.Id = prodId;

                        UpdateImages(doc, prodId, userId);

                        UpdateSubProduct(doc, prdDetail,userId);
                    }
                    return prdDetail;
                }
                else { return null; }
            }
            catch (Exception ex) {
                LogHelper.WriteWebLog("GetDetail异常,url:" + url, ex);
                throw ex;
            }
        }

        private static string GetHtmlRet(string url) {
            //url = " http://httpbin.org/get?show_env=1 ";
            HttpHelper httpHelper = new HttpHelper();
            HttpItem httpItem = new HttpItem();
            httpItem.URL = url;
            httpItem.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            httpItem.Cookie = "cna=Mt3LEbT0TUgCAT2sI6S59CxV; ali_ab=180.162.31.19.1529591322333.2; __utma=62251820.1111960792.1564225697.1564225697.1564225697.1; __utmz=62251820.1564225697.1.1.utmcsr=open.1688.com|utmccn=(referral)|utmcmd=referral|utmcct=/doc/profitModel.htm; ali_apache_id=11.23.109.12.1564237079648.314084.6; taklid=1c616ed267604b69b99f4cb367fec4d8; hng=CN%7Czh-CN%7CCNY%7C156; __last_loginid__=t_1481877651143_0864; alicnweb=touch_tb_at%3D1578581213488%7Clastlogonid%3Dt_1481877651143_0864%7ChomeIdttS%3D92239724384808838068891303300610203016%7ChomeIdttSAction%3Dtrue; ad_prefer=\"2020/01/09 22:47:04\"; h_keys=\"%u8fde%u8863%u88d9#%u6e05%u98ce%u5377%u7eb8%u539f%u6728%u91d1%u88c54%u5c42#%u6e05%u98ce%u5377%u7eb8#%u96ea%u7eba%u886b#%u5145%u7535%u5b9d#2019%u5973%u7ae5%u8fde%u8863%u88d9#tplink%u8def%u7531%u5668#%u5145%u6c14%u6cf3%u8863#%u54ea%u4e9b%u5546%u54c1%u4e0d%u53d7%u5b63%u8282%u6027%u5f71%u54cd\"; XSRF-TOKEN=9ca73af6-e0ae-4af7-b20b-05b634ca38a9; cookie2=181b224489c2313229d66109452579c8; t=f1bd4595b66a5660193ababb3284a36e; _tb_token_=367b0e773be8d; ali_apache_tracktmp=c_w_signed=Y; _show_force_unbind_div_=b2b-25776425984_false; _show_sys_unbind_div_=b2b-25776425984_false; _show_user_unbind_div_=b2b-25776425984_false; __rn_alert__=false; _csrf_token=1578581773496; cookie1=U7KtbkzYNCKQSfr9uvKydhookxKBwkEsQJ0JCUNfG04%3D; cookie17=VyUFNX%2BtmYU%3D; sg=29d; csg=55e46a29; lid=zhang8722; unb=49989309; uc4=nk4=0%40GwlAyxlL2CAntNZP84JzGJ%2B%2FzPU%3D&id4=0%40VXJ0X5VcOlg3pXBcOFQzrkezpw%3D%3D; __cn_logon__=true; __cn_logon_id__=zhang8722; ali_apache_track=c_mid=b2b-49989309|c_lid=zhang8722|c_ms=1; _nk_=zhang8722; last_mid=b2b-49989309; _is_show_loginId_change_block_=b2b-49989309_true; _old_loginId_=b2b-zhang8722; _current_loginId=zhang8722; l=dBEdIYiHqjLa6W8sBOCwourza77OSIRAguPzaNbMi_5dwTLsXabOoY2oVnp6VjWftr8B4hSbuwv9-etlAejZ2iyWmNw0nxDc.; isg=BDk5zzL4Qz_HQhy0AxZt84DPSKXT7iz7gHEwEFtutWDf4ll0o5Y9yKd6YKax2sUw";
            httpItem.UserAgent = "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5";
            //httpItem.ProxyIp = "114.239.252.2:808";  //117.80.4.174	808 ||60.169.240.11	808  || 49.70.32.138	808 || 61.128.208.94	3128 ||60.172.85.193:808
            httpItem.SecurityProtocolType = SecurityProtocolType.Tls;
            HttpResult result = httpHelper.GetHtml(httpItem);

            if (result != null) {
                return result.Html;
            }
            return string.Empty;
        }

        private static int CreateProduct(ProductDetail prdDetail, List<ExportFields> exportfields, HtmlDocument doc) {
            int prodId = -1;
            prdDetail.Title = GetElementVal(doc, "//*[@id=\"mod-detail-title\"]/h1");
            prdDetail.Price = GetElementVal(doc, "//*[@id=\"mod-detail-price\"]/div/table/tr[1]/td[2]/div/span[2]").ToDecimal();
            prdDetail.Price = prdDetail.Price < 0 ? GetElementVal(doc, "//*[@id=\"mod-detail-price\"]/div/table/tr[1]/td[2]/span[2]").ToDecimal() : prdDetail.Price;
            prdDetail.ImageUrl = GetElementVal(doc, "//*[@id=\"mod-detail-bd\"]/div[1]/div/div/div/div/div[1]/div/a/img", "src");
            //prdDetail.TableName = "product0";

            Dictionary<string, string> detailConfig = new Dictionary<string, string>();
            HtmlNode kuajingdl = doc.DocumentNode.SelectSingleNode("//*[@id=\"site_content\"]/div[1]/div/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[1]/div/dl");
            if (kuajingdl != null) {
                HtmlNodeCollection kuajingProps = kuajingdl.SelectNodes("./dd/span");
                if (kuajingProps != null && kuajingProps.Count > 0) {
                    HtmlNode node;
                    foreach (var item in kuajingProps) {
                        node = item.SelectSingleNode("b");
                        if (node != null) {
                            detailConfig[node.InnerHtml] = item.SelectSingleNode("em").InnerHtml;
                        }
                    }
                }
            }       

            HtmlNode table = doc.DocumentNode.SelectSingleNode("//*[@id=\"mod-detail-attributes\"]/div[1]/table");
            if (table != null) {
                HtmlNodeCollection trs = table.SelectNodes("./tbody/tr");
                foreach (var tr in trs) {
                    HtmlNodeCollection tds = tr.SelectNodes("./td");
                    for (int i = 0; i < tds.Count / 2; i++) {
                        if (!String.IsNullOrEmpty(tds[i * 2].InnerHtml) && !String.IsNullOrEmpty(tds[i * 2 + 1].InnerHtml)) {
                            detailConfig[tds[i * 2].InnerHtml] = tds[i * 2 + 1].InnerHtml;
                        }                       
                    }
                }

                if (detailConfig != null) {
                    prdDetail.Description = SerializerHelper.JsonSerialized<Dictionary<string, string>>(detailConfig);
                    //计算关键字段
                    if (exportfields != null) {
                        Dictionary<string, string> keyAttributs = new Dictionary<string, string>();
                        exportfields.ForEach(h => {
                            keyAttributs[h.FieldName] = detailConfig.ContainsKey(h.FieldName) ? detailConfig[h.FieldName] : "";
                        });

                        prdDetail.KeyAttributes = SerializerHelper.JsonSerialized<Dictionary<string, string>>(keyAttributs);
                    }
                }
              
                prodId = productService.InsertModel(prdDetail);
            }
            else {
                LogHelper.WriteWebLog("table is null,ProductId:" + prdDetail.Id);
            }
            return prodId;
        }

        public static int UpdateImages(HtmlDocument doc, int productId, int userId) {
            int ret = -1;
            try {
                List<ProductImage> imageList = new List<ProductImage>();
                HtmlNodeCollection imgNodes = doc.DocumentNode.SelectNodes("//*[@id=\"dt-tab\"]/div/ul/li");
                if (imgNodes != null && imgNodes.Count >0) {
                    foreach (var item in imgNodes) {
                        string imgJson = item.Attributes["data-imgs"].Value;
                        if (!string.IsNullOrEmpty(imgJson)) {
                            dynamic imageInfo = SerializerHelper.JsonDeserialized<dynamic>(imgJson);
                            if (imageInfo != null) {
                                imageList.Add(new ProductImage(productId, imageInfo.original.Value, 1, userId,1));
                            }
                        }                      
                    }

                    String imgDetail = GetElementVal(doc, "//*[@id=\"mod-detail-description\"]", "data-mod-config").Replace("&quot", "");
                    if (!string.IsNullOrEmpty(imgDetail)) {
                        imageList.AddRange(GetDetailImags(productId, userId, imgDetail));
                    }

                    ret = productImgService.SaveImages(imageList);
                }
            }
            catch (Exception ex) {
                LogHelper.WriteWebLog("GetImages异常,productId:" + productId, ex);
                throw ex;
            }
            return ret;       
        }

        private static List<ProductImage> GetDetailImags(int productId, int userId, string imgDetail) {
            List<ProductImage> prodImageList = new List<ProductImage>();
            String imageUrl = HtmlUtils.GetMatchedStr(urlPattern, imgDetail);
            if (!string.IsNullOrEmpty(imgDetail)) {
                string imgDetailUrls = GetHtmlRet(imageUrl);
                List<string> imageList = HtmlUtils.GetMatchedList(urlPattern, imgDetailUrls);
                if (imageList != null) {
                    imageList.ForEach(m => {
                        if (m.EndsWith("jpg") || (m.EndsWith("jpeg"))) {
                            prodImageList.Add(new ProductImage(productId, m, 2, userId, 1));
                        }
                    });
                }
            }
            return prodImageList;
        }

        private static string GetElementVal(HtmlDocument doc, string xpath, string attri = "") {
            HtmlNode node = doc.DocumentNode.SelectSingleNode(xpath);
            return node == null ? "" : (attri == "" ? node.InnerText : node.Attributes[attri].Value);
        }


        public static Boolean UpdateSubProduct(HtmlDocument doc, ProductDetail prodDetail, int uId) {
            try {
                string pageHtml = doc.DocumentNode.InnerHtml;
                int stIdx = pageHtml.IndexOf("iDetailData");
                int edIdx = pageHtml.IndexOf("iDetailData.allTagIds");
                if (edIdx <= stIdx) return false;
                string initConfig = pageHtml.Substring(stIdx + 13, edIdx - stIdx - 19).Replace("\t", "").Replace("\r", "").Replace("\n", "").Replace(" ", "");
                dynamic subProdConfig = SerializerHelper.JsonDeserialized<dynamic>(initConfig);
                if (subProdConfig != null && subProdConfig.sku != null) {

                    List<SubProduct> subProductList = new List<SubProduct>();
                    List<SubProductImage> subProductImageList = new List<SubProductImage>();
                    List<SubProductSize> subProductSizeList = new List<SubProductSize>();
                    int colorCnt = subProdConfig.sku.skuProps[0].value.Count;  //颜色
                    string color, imgUrl, skuId = string.Empty;
                    //部分商品只有颜色，如包
                    if (subProdConfig.sku.skuProps.Count == 1) {
                        for (int i = 0; i < colorCnt; i++) {
                            color = subProdConfig.sku.skuProps[0].value[i].name.Value;
                            imgUrl = subProdConfig.sku.skuProps[0].value[i].imageUrl == null ? "" : subProdConfig.sku.skuProps[0].value[i].imageUrl.Value;
                            imgUrl = string.IsNullOrEmpty(imgUrl) ? "/Areas/Admin/Content/images/no_img.jpg" : imgUrl;
                            skuId = string.Format("{0}_{1}", prodDetail.SkuId, color);
                            subProductList.Add(new SubProduct(prodDetail.UserId) { ProductId = prodDetail.Id, Color = color, Price = prodDetail.Price, ImageUrl = imgUrl, SkuId = skuId });
                            subProductImageList.Add(new SubProductImage(prodDetail.Id, color, imgUrl, uId));
                        }
                    }
                    else if (subProdConfig.sku.skuProps.Count == 2) {
                        int sizeCnt = subProdConfig.sku.skuProps[1].value.Count;   //尺码
                        for (int i = 0; i < colorCnt; i++) {
                            color = subProdConfig.sku.skuProps[0].value[i].name.Value;
                            imgUrl = subProdConfig.sku.skuProps[0].value[i].imageUrl == null ? "" : subProdConfig.sku.skuProps[0].value[i].imageUrl.Value;
                            imgUrl = string.IsNullOrEmpty(imgUrl) ? "/Areas/Admin/Content/images/no_img.jpg" : imgUrl;
                            subProductImageList.Add(new SubProductImage(prodDetail.Id, color, imgUrl, uId));

                            //for (int j = 0; j < sizeCnt; j++) {
                            //    string size = subProdConfig.sku.skuProps[1].value[j].name.Value;
                            //    skuId = string.Format("{0}_{1}_{2}", prodDetail.SkuId, color, size);
                            //    subProductList.Add(new SubProduct(prodDetail.UserId) { ProductId = prodDetail.Id, Color = color, Size = size, Price = prodDetail.Price, ImageUrl = imgUrl, SkuId = skuId });
                            //}
                        }
                        for (int j = 0; j < sizeCnt; j++) {
                            string size = subProdConfig.sku.skuProps[1].value[j].name.Value;
                            subProductSizeList.Add(new SubProductSize(prodDetail.Id, size, prodDetail.Price, uId));
                        }
                    }
                    int saveSizeRet = subProductSizeService.SaveSubProductSize(subProductSizeList);
                    int saveImageRet = subProductImageService.SaveSubProductImages(subProductImageList);
                    return saveSizeRet > 0 && saveImageRet > 0;
                }
            }
            catch (Exception ex) {
                LogHelper.WriteWebLog("GetSubProduct异常", ex);
                throw ex;
            }
            return false;
        }

    }
}
 